/*=========================================================================================
  This file is a part of BioDao.
  Copyright (C) 2011, Fu Limin. Email: fu@daovm.net, limin.fu@yahoo.com

  This software is free software; you can redistribute it and/or modify it under the terms
  of the GNU Lesser General Public License as published by the Free Software Foundation;
  either version 2.1 of the License, or (at your option) any later version.

  This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  See the GNU Lesser General Public License for more details.
  =========================================================================================*/

#include"daoxSequence.h"

DAO_INIT_MODULE

DaoxSequence* DaoxSequence_New( DString *des, DString *seq )
{
	DaoxSequence *self = (DaoxSequence*) dao_calloc( 1, sizeof(DaoxSequence) );
	DaoCdata_InitCommon( (DaoCdata*) self, & DaoxSequence_Typer );
	self->des = des ? DString_Copy( des ) : DString_New(1);
	self->seq = seq ? DString_Copy( seq ) : DString_New(1);
	DString_ToMBS( self->des );
	DString_ToMBS( self->seq );
	return self;
}
void DaoxSequence_Delete( DaoxSequence *self )
{
	DString_Delete( self->des );
	DString_Delete( self->seq );
}
void DaoxSequence_Copy( DaoxSequence *self, DaoxSequence *other )
{
	DString_Assign( self->des, other->des );
	DString_Assign( self->seq, other->seq );
}

static void Sequence_New( DaoProcess *proc, DaoValue *p[], int N )
{
	DaoxSequence *self = DaoxSequence_New( p[0]->xString.data, p[1]->xString.data );
	DaoProcess_PutValue( proc, (DaoValue*) self );
}
static void Sequence_GetDescription( DaoProcess *proc, DaoValue *p[], int N )
{
	DaoxSequence *self = (DaoxSequence*) p[0];
	DaoProcess_PutString( proc, self->des );
}
static void Sequence_GetSequence( DaoProcess *proc, DaoValue *p[], int N )
{
	DaoxSequence *self = (DaoxSequence*) p[0];
	DaoProcess_PutString( proc, self->seq );
}
static void Sequence_SetDescription( DaoProcess *proc, DaoValue *p[], int N )
{
	DaoxSequence *self = (DaoxSequence*) p[0];
	DString_Assign( self->des, p[1]->xString.data );
	DString_ToMBS( self->des );
}
static void Sequence_SetSequence( DaoProcess *proc, DaoValue *p[], int N )
{
	DaoxSequence *self = (DaoxSequence*) p[0];
	DString_Assign( self->seq, p[1]->xString.data );
	DString_ToMBS( self->seq );
}

static DaoFuncItem sequenceMeths[]=
{
	{ Sequence_New,   "Sequence( seq :string, seq = '', qs = '' ) => Sequence" },
	{ Sequence_GetDescription, ".description( self :Sequence ) => string" },
	{ Sequence_GetSequence,    ".data( self :Sequence ) => string" },
	{ Sequence_SetDescription, ".description=( self :Sequence, des :string )" },
	{ Sequence_SetSequence,    ".data=( self :Sequence, data :string )" },
	{ NULL, NULL }
};

DaoTypeBase DaoxSequence_Typer = 
{ "Sequence", NULL, NULL, sequenceMeths, {0}, {0}, (FuncPtrDel)DaoxSequence_Delete, NULL };

DaoxSequenceQS* DaoxSequenceQS_New( DString *des, DString *seq, DString *qs )
{
	DaoxSequenceQS *self = (DaoxSequenceQS*) dao_calloc( 1, sizeof(DaoxSequenceQS) );
	DaoCdata_InitCommon( (DaoCdata*) self, & DaoxSequenceQS_Typer );
	self->des = des ? DString_Copy( des ) : DString_New(1);
	self->seq = seq ? DString_Copy( seq ) : DString_New(1);
	self->qs = qs ? DString_Copy( qs ) : DString_New(1);
	DString_ToMBS( self->des );
	DString_ToMBS( self->seq );
	DString_ToMBS( self->qs );
	return self;
}
void DaoxSequenceQS_Delete( DaoxSequenceQS *self )
{
	DString_Delete( self->des );
	DString_Delete( self->seq );
	DString_Delete( self->qs );
}
void DaoxSequenceQS_Copy( DaoxSequenceQS *self, DaoxSequenceQS *other )
{
	DString_Assign( self->des, other->des );
	DString_Assign( self->seq, other->seq );
	DString_Assign( self->qs, other->qs );
}

static void SequenceQS_New( DaoProcess *proc, DaoValue *p[], int N )
{
	DString *qs = N == 3 ? p[2]->xString.data : NULL;
	DaoxSequenceQS *self = DaoxSequenceQS_New( p[0]->xString.data, p[1]->xString.data, qs );
	DaoProcess_PutValue( proc, (DaoValue*) self );
}
static void SequenceQS_GetQScore( DaoProcess *proc, DaoValue *p[], int N )
{
	DaoxSequenceQS *self = (DaoxSequenceQS*) p[0];
	DaoProcess_PutString( proc, self->qs );
}
static void SequenceQS_SetQScore( DaoProcess *proc, DaoValue *p[], int N )
{
	DaoxSequenceQS *self = (DaoxSequenceQS*) p[0];
	DString_Assign( self->qs, p[1]->xString.data );
	DString_ToMBS( self->qs );
}

static DaoFuncItem sequenceQSMeths[]=
{
	{ SequenceQS_New,   "SequenceQS( seq :string, des = '', qs = '' ) => SequenceQS" },
	{ Sequence_GetDescription, ".qscore( self :Sequence ) => string" },
	{ Sequence_SetDescription, ".qscore=( self :Sequence, qs :string )" },
	{ NULL, NULL }
};

DaoTypeBase DaoxSequenceQS_Typer = 
{ "SequenceQS", NULL, NULL, sequenceQSMeths, {&DaoxSequence_Typer,0}, {0}, 
	(FuncPtrDel)DaoxSequenceQS_Delete, NULL };

int DaoOnLoad( DaoVmSpace *vmSpace, DaoNamespace *ns )
{
	DaoNamespace_WrapType( ns, & DaoxSequence_Typer, 0 );
	DaoNamespace_WrapType( ns, & DaoxSequenceQS_Typer, 0 );
	return 0;
}
